package tech.eyao.hs60x.annotation.aop;

import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.joda.time.LocalDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.PushPayload;
import tech.eyao.hs60x.co.AccountCo;
import tech.eyao.hs60x.common.CommonConstants;
import tech.eyao.hs60x.common.ConstantsKey;
import tech.eyao.hs60x.dao.ZoneDao;
import tech.eyao.hs60x.model.domain.SafetyZoneDO;
import tech.eyao.hs60x.redis.template.AccountCoRedisTemplate;
import tech.eyao.hs60x.utils.JPushUtils;
import tech.eyao.hs60x.utils.LocationUtils;
import tech.eyao.hs60x.utils.TokenUtils;

@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Component
public class ZoneMonitorAop implements Aop { 
	@Autowired
	private ZoneDao zoneDao;
	@Autowired
	private StringRedisTemplate template;
	@Autowired
	private AccountCoRedisTemplate accountCoRedisTemplate;
	
	private static final Logger logger = LoggerFactory.getLogger(ZoneMonitorAop.class);

	@Before("execution(* tech.eyao.hs60x.user.controller.*.info*(..))")
	public void monitor(JoinPoint joinpoint) {
		Object[] args = joinpoint.getArgs();
		if(null!= args) {
			double longitude = (double) args[0];
			double latitude = (double) args[1];
			long watchId = TokenUtils.getUserId();
			if(watchId <= 0 || longitude <=0 || latitude <= 0) {
				return;
			}
			try {
				this.execute(watchId,longitude,latitude);
			} catch (Exception e) {
				logger.error("[ZoneMonitorAop monitor] error .", e);
			}
		}
	}
	
	
	private void execute(long watchId, double longitude, double latitude) throws Exception {
		List<SafetyZoneDO> list = zoneDao.list(watchId);
		boolean isNext = Boolean.TRUE;
		if(CollectionUtils.isEmpty(list)) {
			logger.info("ZoneMonitor{} 未设置安全区域", watchId);
			isNext = Boolean.FALSE;
		}
		SafetyZoneDO safetyZoneDO = null;
		boolean whetherIn = Boolean.FALSE;
		
		if(isDay() && isNext) {
			// 是否存在某一个安全区域内
			for(SafetyZoneDO s : list) {
				if(!LocationUtils.isWithin(latitude, longitude, s.getLatitude(), s.getLongitude(), s.getR())) {
					safetyZoneDO = s;
					whetherIn = Boolean.TRUE;
					break;
				}
			}
			
			String adminAccountId = template.opsForValue().get(ConstantsKey.getWatchAdminKey(watchId));
			AccountCo accountCo = accountCoRedisTemplate.opsForValue().get(ConstantsKey.getAccountKey(watchId));
			
			if(!whetherIn) {
				if(StringUtils.isEmpty(template.opsForValue().get(ConstantsKey.getZoneOutKey(watchId)))) {
					logger.info("ZoneMonitor watchId={} 离开安全区域 管理员ID{}", watchId, adminAccountId);
					if(StringUtils.isNotEmpty(adminAccountId)) {
						// jpush
						PushPayload pushPayload = JPushUtils.buildPushObject_all_alias_alert(adminAccountId, String.format("宝贝%s离开安全区域",StringUtils.defaultString(accountCo.nickName)));
						JPushUtils.getPhoneInstance().sendPush(pushPayload);
					}
					
					template.opsForValue().set(ConstantsKey.getZoneOutKey(watchId), "1", CommonConstants.ZONE_OUT_TIME , TimeUnit.SECONDS);
				}
			} else {
				// 上次提醒区域与当前区域一致则不提醒
				if(String.valueOf(safetyZoneDO.getId()).equals(template.opsForValue().get(ConstantsKey.getCurrZoneKey(watchId + safetyZoneDO.getId())))) {
					return;
				}
				logger.info("ZoneMonitor watchId={} 进入安全区域{}", watchId, safetyZoneDO.getAddress());
				
				if(StringUtils.isNotEmpty(adminAccountId)) {
					// jpush推送信息
					PushPayload pushPayload = JPushUtils.buildPushObject_all_alias_alert(adminAccountId, String.format("宝贝%s进入安全区域%s",StringUtils.defaultString(accountCo.nickName),StringUtils.defaultString(safetyZoneDO.getAddress())));
					JPushUtils.getPhoneInstance().sendPush(pushPayload);
				}
				template.opsForValue().set(ConstantsKey.getCurrZoneKey(watchId + safetyZoneDO.getId()), String.valueOf(safetyZoneDO.getId()));
			}
		}
	}

	/**
	 * 起始时间早7点 晚8点
	 * @return
	 */
	private boolean isDay() {
		int hours = LocalDateTime.now().getHourOfDay();
		return hours >= CommonConstants.DAY_TIME && hours <= CommonConstants.NIGHT_TIME;
	}
	
	public static void main(String[] args) throws Exception {
		JPushClient client = JPushUtils.getPhoneInstance();
		PushResult result = client.sendMessageAll("test1212");
		
		PushPayload pushPayload = JPushUtils.buildPushObject_all_all_alert("宝贝离开安全区");
		JPushUtils.getPhoneInstance().sendPush(pushPayload);
	}

	@Override
	public Object getData(Object... params) {
		return null;
	}
}
